package com.example.demo.manager;

import com.example.demo.enums.OrderStatusEnum;
import com.example.demo.operator.AbstractOrderOperator;
import com.example.demo.processor.AbstractOrderProcessor;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author zhy
 * @version 1.0.0
 * @ClassName OrderStatusManager.java
 * @Description TODO
 * @createTime 2020年12月02日 14:30:00
 */
@Component
public class OrderStatusManager {

    public static Map<Integer, AbstractOrderOperator> orderOperatorMaps = new ConcurrentHashMap<>();

    public static Map<Integer, AbstractOrderProcessor> orderProcessorMaps = new ConcurrentHashMap<>();

    public OrderStatusManager() {

    }

    public int handleEvent(final String orderId, OrderStatusEnum event, final int status) {
        if (this.isFinalStatus(status)) {
            throw new IllegalArgumentException("handle event can't process final status order.");
        }
        AbstractOrderOperator abstractOrderOperator = this.getStatusOperator(event);
        int resultStatus = abstractOrderOperator.handleEvent(status, event);
        AbstractOrderProcessor abstractOrderProcessor = this.getOrderProcessor(event);
        if (!abstractOrderProcessor.process(orderId, resultStatus)) {
            throw new IllegalStateException(String.format("订单状态流转失败，订单id:%s", orderId));
        }
        return resultStatus;
    }

    private AbstractOrderOperator getStatusOperator(OrderStatusEnum event) {
        AbstractOrderOperator orderOperator = null;
        for (Map.Entry<Integer, AbstractOrderOperator> entry : orderOperatorMaps.entrySet()) {
            if (event.status == entry.getKey()) {
                orderOperator = entry.getValue();
            }
        }
        if (null == orderOperator) {
            throw new IllegalArgumentException(String.format("can't find proper operator. The parameter status :%s", event.toString()));
        }
        return orderOperator;
    }


    private AbstractOrderProcessor getOrderProcessor(OrderStatusEnum event) {
        AbstractOrderProcessor orderProcessor = null;
        for (Map.Entry<Integer, AbstractOrderProcessor> entry : orderProcessorMaps.entrySet()) {
            if (event.status == entry.getKey()) {
                orderProcessor = entry.getValue();
            }
        }
        if (null == orderProcessor) {
            throw new IllegalArgumentException(String.format("can't find proper processor. The parameter status :%s", event.toString()));
        }
        return orderProcessor;
    }

    private boolean isFinalStatus(int status) {
        return OrderStatusEnum.ORDER_FINISHED.status == status;
    }
}
